<template>
  <div class="avatar-upload">
    <!-- 头像显示区域 -->
    <div 
      class="avatar-container"
      :class="{ 'uploading': isUploading, 'error': hasError }"
      @click="handleAvatarClick"
      @dragover.prevent
      @dragenter.prevent
      @drop.prevent="handleDrop"
    >
      <!-- 头像图片 -->
      <div class="avatar-image">
        <img 
          v-if="avatarUrl && !isUploading" 
          :src="avatarUrl" 
          :alt="altText"
          class="avatar-img"
        />
        <div v-else-if="!avatarUrl && !isUploading" class="default-avatar">
          <span class="default-text">{{ defaultText }}</span>
        </div>
        <!-- 上传中状态 -->
        <div v-if="isUploading" class="uploading-overlay">
          <div class="uploading-spinner"></div>
          <div class="uploading-text">上传中...</div>
          <div v-if="uploadProgress > 0" class="upload-progress">
            <div class="progress-bar" :style="{ width: uploadProgress + '%' }"></div>
          </div>
        </div>
        <!-- 错误状态 -->
        <div v-if="hasError" class="error-overlay">
          <div class="error-icon">⚠️</div>
          <div class="error-text">上传失败</div>
        </div>
      </div>
      
      <!-- 悬停提示 -->
      <div v-if="!isUploading && !hasError" class="hover-overlay">
        <div class="upload-icon">📷</div>
        <div class="upload-text">点击更换头像</div>
      </div>
    </div>
    
    <!-- 文件选择输入框 -->
    <input 
      ref="fileInput"
      type="file"
      accept="image/jpeg,image/jpg,image/png,image/gif"
      style="display: none"
      @change="handleFileSelect"
    />
    
    <!-- 预览弹窗 -->
    <div v-if="showPreview" class="preview-overlay" @click="closePreview">
      <div class="preview-content" @click.stop>
        <div class="preview-header">
          <h3>头像预览</h3>
          <button class="close-btn" @click="closePreview">×</button>
        </div>
        <div class="preview-body">
          <div class="preview-image">
            <img :src="previewUrl" alt="预览图片" />
          </div>
          <div class="preview-info">
            <p><strong>文件名:</strong> {{ selectedFile?.name }}</p>
            <p><strong>文件大小:</strong> {{ formatFileSize(selectedFile?.size) }}</p>
            <p><strong>文件类型:</strong> {{ selectedFile?.type }}</p>
          </div>
        </div>
        <div class="preview-actions">
          <button class="btn-cancel" @click="closePreview">取消</button>
          <button class="btn-confirm" @click="confirmUpload" :disabled="isUploading">
            {{ isUploading ? '上传中...' : '确认上传' }}
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

// Props
const props = defineProps({
  // 当前头像URL
  avatarUrl: {
    type: String,
    default: ''
  },
  // 头像尺寸
  size: {
    type: [String, Number],
    default: 80
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 最大文件大小（MB）
  maxSize: {
    type: Number,
    default: 2
  },
  // 允许的文件类型
  accept: {
    type: Array,
    default: () => ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
  },
  // 默认头像文本
  defaultText: {
    type: String,
    default: '头像'
  },
  // 图片alt文本
  altText: {
    type: String,
    default: '用户头像'
  }
})

// Emits
const emit = defineEmits(['upload-success', 'upload-error', 'upload-start', 'upload-progress'])

// 响应式数据
const fileInput = ref(null)
const isUploading = ref(false)
const hasError = ref(false)
const showPreview = ref(false)
const selectedFile = ref(null)
const previewUrl = ref('')
const uploadProgress = ref(0)

// 计算属性
const avatarSize = computed(() => {
  return typeof props.size === 'number' ? `${props.size}px` : props.size
})

// 监听头像URL变化，清除错误状态
watch(() => props.avatarUrl, () => {
  hasError.value = false
})

// 处理头像点击
const handleAvatarClick = () => {
  if (props.disabled || isUploading.value) return
  fileInput.value?.click()
}

// 处理文件选择
const handleFileSelect = (event) => {
  const file = event.target.files?.[0]
  if (file) {
    validateAndPreviewFile(file)
  }
}

// 处理拖拽上传
const handleDrop = (event) => {
  if (props.disabled || isUploading.value) return
  
  const files = event.dataTransfer.files
  if (files.length > 0) {
    validateAndPreviewFile(files[0])
  }
}

// 验证文件并显示预览
const validateAndPreviewFile = (file) => {
  // 验证文件类型
  if (!props.accept.includes(file.type)) {
    ElMessage.error(`不支持的文件格式，请选择 ${props.accept.join(', ')} 格式的图片`)
    return
  }
  
  // 验证文件大小
  const maxSizeBytes = props.maxSize * 1024 * 1024
  if (file.size > maxSizeBytes) {
    ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)
    return
  }
  
  // 创建预览URL
  const reader = new FileReader()
  reader.onload = (e) => {
    previewUrl.value = e.target.result
    selectedFile.value = file
    showPreview.value = true
  }
  reader.readAsDataURL(file)
}

// 关闭预览
const closePreview = () => {
  showPreview.value = false
  previewUrl.value = ''
  selectedFile.value = null
  // 清空文件输入框
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}

// 确认上传
const confirmUpload = async () => {
  if (!selectedFile.value) return
  
  isUploading.value = true
  hasError.value = false
  uploadProgress.value = 0
  
  emit('upload-start', selectedFile.value)
  
  try {
    // 使用用户store的完整上传流程
    const avatarUrl = await userStore.uploadUserAvatar(selectedFile.value)
    
    emit('upload-success', avatarUrl)
    ElMessage.success('头像上传成功')
    closePreview()
  } catch (error) {
    console.error('头像上传失败:', error)
    hasError.value = true
    emit('upload-error', error)
    ElMessage.error(error.message || '头像上传失败，请重试')
  } finally {
    isUploading.value = false
    uploadProgress.value = 0
  }
}

// 注意：这里移除了自定义的上传函数，直接使用用户store的完整上传流程

// 注意：更新头像的逻辑现在由用户store统一处理

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 暴露方法给父组件
defineExpose({
  upload: confirmUpload,
  reset: () => {
    hasError.value = false
    isUploading.value = false
    uploadProgress.value = 0
  }
})
</script>

<style scoped>
.avatar-upload {
  display: inline-block;
}

.avatar-container {
  position: relative;
  width: v-bind(avatarSize);
  height: v-bind(avatarSize);
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  border: 3px solid #e1e5e9;
  transition: all 0.3s ease;
  background: #f8f9fa;
}

.avatar-container:hover {
  border-color: #667eea;
  box-shadow: 0 4px 16px rgba(102, 126, 234, 0.2);
}

.avatar-container.uploading {
  border-color: #667eea;
  cursor: not-allowed;
}

.avatar-container.error {
  border-color: #ff4757;
}

.avatar-image {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.default-avatar {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.default-text {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
}

.hover-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
  color: white;
}

.avatar-container:hover .hover-overlay {
  opacity: 1;
}

.upload-icon {
  font-size: 20px;
  margin-bottom: 4px;
}

.upload-text {
  font-size: 12px;
  font-weight: 500;
}

.uploading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(102, 126, 234, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
}

.uploading-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top: 2px solid white;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 8px;
}

.uploading-text {
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 8px;
}

.upload-progress {
  width: 60%;
  height: 4px;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 2px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background: white;
  transition: width 0.3s ease;
}

.error-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 71, 87, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
}

.error-icon {
  font-size: 20px;
  margin-bottom: 4px;
}

.error-text {
  font-size: 12px;
  font-weight: 500;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 预览弹窗样式 */
.preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}

.preview-content {
  background: white;
  border-radius: 16px;
  width: 100%;
  max-width: 400px;
  max-height: 90vh;
  overflow: hidden;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}

.preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid #f0f0f0;
}

.preview-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.close-btn {
  background: none;
  border: none;
  font-size: 24px;
  color: #999;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: all 0.3s ease;
}

.close-btn:hover {
  background: #f5f5f5;
  color: #666;
}

.preview-body {
  padding: 24px;
}

.preview-image {
  width: 100%;
  height: 200px;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 16px;
  background: #f8f9fa;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.preview-info {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
}

.preview-info p {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: #666;
}

.preview-info p:last-child {
  margin-bottom: 0;
}

.preview-actions {
  display: flex;
  gap: 12px;
  padding: 20px 24px;
  border-top: 1px solid #f0f0f0;
}

.btn-cancel {
  flex: 1;
  padding: 12px 20px;
  border: 2px solid #e1e5e9;
  border-radius: 10px;
  background: white;
  color: #666;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-cancel:hover {
  border-color: #ccc;
  background: #f8f9fa;
}

.btn-confirm {
  flex: 1;
  padding: 12px 20px;
  border: none;
  border-radius: 10px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-confirm:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}

.btn-confirm:disabled {
  opacity: 0.7;
  cursor: not-allowed;
  transform: none;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .preview-content {
    margin: 20px;
    max-width: calc(100% - 40px);
  }
  
  .preview-header,
  .preview-body,
  .preview-actions {
    padding: 16px 20px;
  }
  
  .preview-image {
    height: 150px;
  }
}
</style>
